#pragma once
#include<iostream>
#include<vector>
#include<cassert>
#include<cstring>
#include"Log.hpp"
#define BUFFER_SIZE 1024//缓冲区大小
class Buffer{
    private:
        std::vector<char> _buffer;//缓冲区
        size_t _read_index;//读指针
        size_t _write_index;//写指针
    public:
        Buffer():_read_index(0),_write_index(0),_buffer(20){}
        ~Buffer(){}
        size_t GetBufferSize(){return _buffer.size();}    

        char *GetBegin(){return &_buffer[0];}//获取缓冲区首地址
        char *GetReadPointer() {return &_buffer[_read_index];}//获取读指针
        char *GetWritePointer(){return &_buffer[_write_index];}//获取写指针
        
        size_t HeadSpace(){return _read_index;}//头部空间
        size_t TailSpace(){return _buffer.size() - _write_index;}//尾部空间

        size_t ReadableSize(){return _write_index - _read_index;}//可读大小
        size_t WritableSize(){return _buffer.size() - ReadableSize();}//可写大小
        void TestPrintBuffer()
        {
            for(size_t i=_read_index;i<_write_index;i++){
                std::cout<<_buffer[i];
            }
            std::cout<<std::endl;
        }
        void Write(void *data,size_t len)//不确定数据类型，但是最终都是强转成char*，然后按字节拷贝
        {
            //先判断是否具有足够的空间
            if(len > TailSpace() && len <= WritableSize()){//调整写的位置
                size_t rdsize = ReadableSize();
                _read_index = 0;
                _write_index = rdsize;
                std::copy(GetReadPointer(),GetReadPointer()+rdsize,GetBegin());
                std::copy((char*)data,((char*)data)+len,GetWritePointer());
                _write_index += len;//更新写指针
                return;
            }else if(len > WritableSize()){//缓冲区不够用，扩容
                _buffer.resize(_buffer.size() + len);
            }
            std::copy((char*)data,((char*)data)+len,GetWritePointer());
            _write_index += len;//更新写指针
        }
        void Read(void *buffer,size_t len)//从读指针开始读len个字节，存入buffer
        {
            assert(ReadableSize() >= len);
            std::copy(GetReadPointer(),GetReadPointer()+len,(char *)buffer);
            // LOG("read : %ld",_read_index);
        }
        void MoveReadIndex(size_t len)//移动读指针
        {
            assert(ReadableSize() >= len);
            _read_index += len;
        }
        void ReadAndMove(void *buffer,size_t len)//从读指针开始读len个字节，存入buffer，并移动读指针
        {
            Read(buffer,len);
            _read_index += len;
            // LOG("readandmove : %ld",_read_index);
        }

        char *FindCRLF()//查找换行符
        {
            char *ret = (char *)memchr(GetReadPointer(),'\n',ReadableSize());
            return ret;
        }
        std::string GetLine()//获取一行
        {
            char *pos = FindCRLF();
            if(pos == NULL){
                return "";
            }
            int len = pos - GetReadPointer() + 1;//请求行长度(包括换行符)
            char *buf = new char[len+1];
            ReadAndMove(buf,len);
            std::string line(buf,len);
            delete[] buf;
            return line;
        }
        void Clear() //清空缓冲区
        {
            _read_index = 0;
            _write_index = 0;
        }
};
